package com.yflutter.yfree_app.lib.YFree

import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.net.Uri
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.ProgressBar
import android.widget.TextView
import com.yfree.YConfig
import com.yfree.activities.YActivity
import com.yfree.application.YApplication
import com.yfree.listeners.YAjaxCallBack
import com.yfree.models.YModel
import com.yfree.utils.YAppUtils
import com.yfree.utils.YDataCleanManager
import com.yfree.utils.net.YJsonKV
import com.yfree.views.YProgressDialog
import io.dcloud.feature.sdk.DCSDKInitConfig
import io.dcloud.feature.sdk.DCUniMPSDK
import io.dcloud.feature.sdk.Interface.IDCUniMPAppSplashView
import io.dcloud.feature.sdk.Interface.IUniMP
import io.dcloud.feature.unimp.DCUniMPJSCallback
import net.tsz.afinal.http.AjaxCallBack
import org.json.JSONObject
import java.io.File
import java.util.*

class YUniappModel : YModel {
    var version: String = ""
    var url: String = ""
    var page: String? = null

    constructor() : super()

    constructor(version: String, url: String) : super() {
        this.version = version
        this.url = url
    }
}

class YUniappPlugin {
    var activity: YActivity
    var appid: String
    var checkVersionJkid: String?
    var page: String?
    var arguments: JSONObject?
    var callback: ((String, String, Any?, DCUniMPJSCallback) -> Unit)?

    constructor(activity: YActivity, page: String? = null, appid: String = "__UNI__AAAAAAA", checkVersionJkid: String? = null, arguments: Map<*, *>? = null, callback: ((String, String, Any?, DCUniMPJSCallback) -> Unit)? = null) {
        this.activity = activity
        this.appid = appid
        this.checkVersionJkid = checkVersionJkid
        this.page = page
        this.arguments = if (arguments == null) null else JSONObject(arguments)
        this.callback = callback
    }

    companion object {
        var applicationContext: Context? = null
        var unimp: IUniMP? = null

        fun yInit(applicationContext: Context) {
            DCUniMPSDK.getInstance().initialize(applicationContext, DCSDKInitConfig.Builder().setCapsule(false).setEnableBackground(false).setUniMPFromRecents(false).build()) { isSuccess ->
                if (!isSuccess) yInit(applicationContext)
            }
        }

        fun sendEvent(event: String, data: String): Boolean? {
            return unimp?.sendUniMPEvent(event, data)
        }

        fun finish() {
            unimp?.closeUniMP()
            unimp = null
        }
    }

    fun run(uniappModel: YUniappModel? = null) {
        if (uniappModel == null && checkVersionJkid == null) {
            activity.yToast("无法确定小程序版本信息")
            return
        }
        if (uniappModel != null) {
            runModel(uniappModel)
            return
        }
        activity.yPost(
                checkVersionJkid,
                YJsonKV()
                        .put("appid", appid),
                object : YAjaxCallBack<YUniappModel>(activity) {
                    override fun onSuccessed(yUniappModels: ArrayList<YUniappModel>) {
                        YProgressDialog.dismissProgress(activity)
                        runModel(yUniappModels.first())
                    }

                    override fun onFail(response: Any?, throwable: Throwable?, code: String?, message: String?) {
                        YProgressDialog.dismissProgress(activity)
                        loadFail("初始化信息失败", uniappModel)
                    }
                }, false
        )
    }

    fun runModel(uniappModel: YUniappModel) {
        if (YConfig.DEBUG)
            getNewVersion(uniappModel)
        else {
            if (DCUniMPSDK.getInstance().isExistsApp(appid)) {
                if ((DCUniMPSDK.getInstance().getAppVersionInfo(appid)["code"]
                                ?: 0).toString().toInt() >= uniappModel.version.toInt()
                )
                    openUniapp()
                else
                    getNewVersion(uniappModel)
            } else
                getNewVersion(uniappModel)
        }
    }

    fun getNewVersion(uniappModel: YUniappModel) {
        YProgressDialog.showProgress(activity)
        val dirPath = "${activity.context.getExternalFilesDir(YConfig.YFreeDir)!!.absolutePath}${YConfig.PROJECTBASEDIR}/Uniapp"
        val dir = File(dirPath)
        YDataCleanManager.deleteDir(dir)
        dir.mkdirs()
        val wgtPath = "$dirPath/${appid}_${uniappModel.version}.wgt"
        YApplication.getFinalHttp().download(uniappModel.url + "?v${Date().time}", wgtPath, object : AjaxCallBack<File>() {
            override fun onSuccess(t: File?) {
                DCUniMPSDK.getInstance().releaseWgtToRunPathFromePath(appid, wgtPath) { code, pArgs ->
                    YProgressDialog.dismissProgress(activity)
                    if (code == 1)
                        openUniapp()
                    else
                        loadFail("加载数据失败", uniappModel)
                    return@releaseWgtToRunPathFromePath null
                }
            }

            override fun onFailure(t: Throwable?, errorNo: Int, strMsg: String?) {
                YProgressDialog.dismissProgress(activity)
                loadFail("获取数据失败", uniappModel)
            }
        })
    }

    fun openUniapp() {
        finish()
        DCUniMPSDK.getInstance().setOnUniMPEventCallBack { appid, event, data, callback ->
            activity.yRunOnUIThread {
                when (event) {
                    "yGetDebug" -> {
                        callback(if (YConfig.DEBUG) "debug" else "release")
                    }
                    "yGetIP" -> {
                        callback(YConfig.IP)
                    }
                    "yGetAppName" -> {
                        callback(YAppUtils.getAppName(activity.context))
                    }
                    "yLog" -> {
                        activity.yLog(data.toString())
                    }
                    "yToast" -> {
                        activity.yToast(data.toString())
                    }
                    "yCopy" -> {
                        (activity.context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager).setPrimaryClip(ClipData.newPlainText("text", data.toString()))
                    }
                    "yOpenBrowser" -> {
                        activity.context.startActivity(Intent().setAction(Intent.ACTION_VIEW).setData(Uri.parse(data.toString())))
                    }
                    else -> this.callback?.invoke(appid, event, data, callback)
                }
            }
        }
        DCUniMPSDK.getInstance().setUniMPOnCloseCallBack {
            unimp = null
        }
        unimp =
                if (page != null && arguments != null)
                    DCUniMPSDK.getInstance().openUniMP(activity.context, appid, SplashView::class.java, page, arguments)
                else if (page == null && arguments != null)
                    DCUniMPSDK.getInstance().openUniMP(activity.context, appid, SplashView::class.java, arguments)
                else if (page != null && arguments == null)
                    DCUniMPSDK.getInstance().openUniMP(activity.context, appid, SplashView::class.java, page)
                else
                    DCUniMPSDK.getInstance().openUniMP(activity.context, appid, SplashView::class.java)
    }

    fun loadFail(message: String, uniappModel: YUniappModel?) {
        activity.yShowBuilder("$message，是否重试？", "重试", { _, _ -> run(uniappModel) }, null, true)
    }

    class SplashView : IDCUniMPAppSplashView {
        var splashView: LinearLayout? = null

        override fun getSplashView(context: Context?, p1: String?, p2: String?, p3: String?): View {
            if (splashView == null) {
                splashView = LinearLayout(context!!)
                splashView!!.setBackgroundColor(Color.WHITE)
                splashView!!.gravity = Gravity.CENTER
                val containerView = LinearLayout(context)
                containerView.orientation = LinearLayout.VERTICAL
                val progressBar = ProgressBar(context)
                containerView.addView(progressBar)
                val textView = TextView(context)
                textView.gravity = Gravity.CENTER
                textView.text = ("\n模块加载中，请稍后")
                containerView.addView(textView)
                splashView!!.addView(containerView)
                splashView!!.setOnTouchListener { _, _ -> return@setOnTouchListener true }
            }
            return splashView!!
        }

        override fun onCloseSplash(rootView: ViewGroup?) {
            rootView?.removeView(splashView)
        }
    }
}